import string
import random
from functools import wraps
from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity
from extension import cache
from flask_mail import Message
from flask import Blueprint, request, jsonify, session
from werkzeug.security import generate_password_hash, check_password_hash
from extension import db, mail
from model import *
import datetime

user_bp = Blueprint('user', __name__)


def admin_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        current_user = get_jwt_identity()
        if current_user['role'] == 'teacher':
            return f(*args, **kwargs)
        else:
            return jsonify({'message': 'You are not logged in!'}), 401

    return decorated_function


def assistant_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        current_user = get_jwt_identity()
        if current_user['role'] == 'assistant':
            return f(*args, **kwargs)
        else:
            return jsonify({'message': 'You are not logged in!'}), 401

    return decorated_function


def student_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        current_user = get_jwt_identity()
        if current_user['role'] == 'student':
            return f(*args, **kwargs)
        else:
            return jsonify({'message': 'You are not logged in!'}), 401
    return decorated_function



@user_bp.route('/login/<role>', methods=['POST'])
def login(role):
    data = request.get_json(force=True)
    print(data)
    uid = data['uid'].strip()
    role = data['role']
    password = data['password']

    if role == "student":
        user = User.query.filter_by(student_id=uid).first()

        if user and check_password_hash(user.password, password):
            data = {
                'uid': user.student_id,
                'name': user.name,
                'college': user.college,
                'grade': user.grade,
                'role': role
            }
            return jsonify({"token": create_access_token(data)}), 200
        else:
            return jsonify({"message": "Invalid credentials"}), 401

    else:
        teacher = Teacher.query.filter_by(teacher_id=uid).first()

        if teacher and check_password_hash(teacher.password, password):
            data = {
                'uid': teacher.teacher_id,
                'name': teacher.name,
                'college': teacher.college,
                'role': role
            }
            return jsonify({"token": create_access_token(data)}), 200
        else:
            return jsonify({"message": "Invalid credentials"}), 401


@user_bp.route('/register', methods=['POST'])
def register():
    data = request.get_json()
    print(data)
    role = data['role']
    # cache_code = cache.get(email)
    # if not cache_code:
    #     return jsonify({"message": "please ask for email verification first"}), 400

    if role == "student":
        name = data['name']
        password = data['password']
        student_id = data['student_id']
        college = data['college']
        grade = data['grade']
        email = data['email']
        if User.query.filter_by(student_id=student_id).first():
            return jsonify({'message': 'User already exists'}), 400
        else:
            new_user = User(student_id, name, generate_password_hash(password, method='pbkdf2:sha256'), college, grade,
                            role, email)
            db.session.add(new_user)
            db.session.commit()
            return jsonify({"message": "User created"}), 200

    if role == "teacher":
        name = data['name']
        password = data['password']
        teacher_id = data['student_id']
        college = data['college']
        if Teacher.query.filter_by(teacher_id=teacher_id).first():
            return jsonify({'message': 'User already exists'}), 400
        else:
            new_teacher = Teacher(teacher_id, name, generate_password_hash(password, method='pbkdf2:sha256'), college)
            db.session.add(new_teacher)
            db.session.commit()
            return jsonify({"message": "teacher created"}), 200


@user_bp.route('/logout', methods=['POST'])
@jwt_required()
def logout():
    return jsonify({"message": "You have been logged out"}), 200


@user_bp.route('/reset_password', methods=['POST'])
def reset_password():
    data = request.get_json()
    code = data['code']
    email = data['email']
    password = data['password']
    user = User.query.filter_by(mail=email).first()
    if not user:
        return jsonify({'message': 'Cannot find user'}), 404
    cache_code = cache.get(email)
    if not cache_code:
        return jsonify({"message": "Please ask for email verification first"}), 400
    if code == cache_code:
        user.set_password(generate_password_hash(password, method='pbkdf2:sha256'))
        db.session.commit()
        return jsonify({"message": "Password reset successful"}), 200
    return jsonify({"message": "Error occurs"}), 400


@user_bp.route('/reset_verify', methods=['GET'])
def verify():
    email = request.args.get('email')
    if not email:
        return jsonify({"message": "Please provide an email"}), 400
    user = User.query.filter_by(email=email).first()
    if user:
        code = send_verification_email(email)
        cache.set(email, code, timeout=300)
        return jsonify({"message": "An email is sent tu your email successful"}), 200
    else:
        return jsonify({"message": "Cannot find the user"}), 404


def send_verification_email(email):
    code = ''.join(random.choices(string.ascii_letters + string.digits, k=6))
    print([email])
    msg = Message(subject='Verification Code',
                  recipients=[email])
    msg.body = f'Your verification code is: {code}'

    try:
        mail.send(msg)
        return code

    except Exception as e:
        print(f"Failed to send email: {e}")
        return None


@user_bp.route('/regist_verify', methods=['GET'])
def regist_verify():
    email = request.args.get('email')
    if (not email):
        return jsonify({"message": "Please enter your email"}), 400
    code = send_verification_email(email)

    cache.set(email, code, timeout=300)
    return jsonify({"message": "An email is sent tu your email successful"}), 200


@user_bp.route('/get_info', methods=['GET'])
@jwt_required()
def get_info():
    current_user = get_jwt_identity()
    print(current_user)
    if current_user:
        user_info = {
            "uid": current_user['uid'],
            "name": current_user['name'],
            "college": current_user['college'],
            'role': current_user['role']
        }
        return jsonify(user_info), 200
    else:
        return jsonify({"message": "User not found"}), 404


# # 发送验证码
# @user_bp.route('/reset_verify', methods=['GET'])
# def reset_verify():
#     email = request.args.get('email')
#     if not email:
#         return jsonify({"message": "请输入邮箱"}), 400
#
#     user = User.query.filter_by(email=email).first()
#     if user:
#         code = send_verification_email(email)
#         if code:
#             cache.set(email, code, timeout=300)  # 验证码缓存5分钟
#             return jsonify({"message": "验证码已发送至邮箱"}), 200
#         else:
#             return jsonify({"message": "发送验证码失败"}), 500
#     else:
#         return jsonify({"message": "找不到该邮箱对应的用户"}), 404
#
#
# # 重置密码
# @user_bp.route('/reset_password', methods=['POST'])
# def reset_password():
#     data = request.get_json()
#     code = data['code']
#     email = data['email']
#     new_password = data['password']
#     user = User.query.filter_by(email=email).first()
#
#     if not user:
#         return jsonify({'message': '找不到用户'}), 404
#
#     cache_code = cache.get(email)
#     if not cache_code:
#         return jsonify({"message": "请先请求验证码"}), 400
#
#     if code == cache_code:
#         user.password = generate_password_hash(new_password, method='pbkdf2:sha256')  # 更新密码
#         db.session.commit()
#         return jsonify({"message": "密码重置成功"}), 200
#
#     return jsonify({"message": "验证码错误"}), 400
#
#
# # 发送邮件验证码
# def send_verification_email(email):
#     code = ''.join(random.choices(string.ascii_letters + string.digits, k=6))  # 生成6位验证码
#     msg = Message(subject='验证码',
#                   recipients=[email])
#     msg.body = f'您的验证码是: {code}'
#
#     try:
#         mail.send(msg)
#         return code
#     except Exception as e:
#         print(f"发送邮件失败: {e}")
#         return None
